#!/usr/bin/env python3
# encoding=utf-8

import os
from word_with_image import replace_word_png
from commom_api import get_product_name_prefix, get_doc_fill_base_info, get_sheet_value, get_word_config_str, check_code_in_list
from docx import Document
from docx.oxml.ns import qn
from docx.shared import Cm, Pt
from docx.shared import RGBColor
from docx.enum.table import WD_ALIGN_VERTICAL, WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_PARAGRAPH_ALIGNMENT

import logging
logger = logging.getLogger(__name__)

def set_doc_cell_format(cell, mval, num=1):
    if num < 1:
        return
    
    # color
    cellcolor = get_word_config_str(num-1, mval, 'color')
    if cellcolor == None:
        rgb = [0, 0, 0]
    else:
        rgb = cellcolor
    cell.paragraphs[0].runs[0].font.color.rgb = RGBColor(rgb[0], rgb[1], rgb[2])

    # bold
    cellbold = get_word_config_str(num-1, mval, 'bold')
    if cellbold == None:
        bold = False
    else:
        bold = True if cellbold != 0 else False
    cell.paragraphs[0].runs[0].bold = bold

def extend_doc_table(wtb, sheet, xlsinfo):
    docname, mode = get_doc_fill_base_info(xlsinfo['code'], xlsinfo['daterange'][0])
    if mode == None:
        return
    
    minrow = 3
    maxrow = len(wtb.rows)
    for key, mval in mode.items():
        if 'wpos' not in mval:
            continue
        if maxrow < mval['wpos'][0]:
            maxrow = mval['wpos'][0]

    if maxrow <= len(wtb.rows):
        addrow = 0
    else:
        addrow = maxrow - len(wtb.rows)
    
    if addrow > 0:
        height = 0
        for i in range(0, addrow):
            wtb.add_row()
        for row in wtb.rows[minrow:]:
            row.height = Cm(1.25)
            height += 1.2
    else:
        height = 7.2

    start_cell = wtb.cell(minrow+1, 3)  # 起始单元格（行3，列0）
    end_cell = wtb.cell(maxrow-1, 5)    # 结束单元格（行4，列2）
    merged_cell = start_cell.merge(end_cell)
    merged_cell.text = ""  # 清空默认文本（可选）
    # 获取合并后单元格的段落对象
    paragraph = merged_cell.paragraphs[0]
    paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 水平居中
    merged_cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

    if xlsinfo['fillpicture']:
        # 插入图片并设置尺寸（单位可用 Cm 或 Inches）
        pngpath = xlsinfo['excel'].replace('.xlsx', '.png')
        run = paragraph.add_run()
        run.add_picture(pngpath, width=Cm(11), height=Cm(height))
        if check_code_in_list(xlsinfo['code'], xlsinfo['daterange'][0], xlsinfo['keepexcelpng']) == False:
            os.remove(pngpath)

def fill_doc_table_dynamic_info(mode, wtb, sheet, xlsinfo):
    isheaderchange = False
    for key, mval in mode.items():
        if 'wpos' not in mval:
            continue
        if len(wtb.rows) < mval['wpos'][0] or len(wtb.columns) < mval['wpos'][1]:
            logger.error(f'max word table [{len(wtb.rows)},{len(wtb.columns)}], please check you config.json')
            continue

        nhkey = key.split('header_')[-1]
        xpos = mval['xpos']
        # xpos = [x-1 for x in mval['xpos']]
        wpos = [x-1 for x in mval['wpos']]
        cell = wtb.cell(wpos[0], wpos[1]-1)        
        cellstr = get_word_config_str(0, mval, 'adddate')
        if cellstr == None:
            cell.text = nhkey
        else:
            cell.text = f"{nhkey}\n({xlsinfo['daterange'][2].replace('-', '/')})"
        set_doc_cell_format(cell, mval, 1)

        
        cell = wtb.cell(wpos[0], wpos[1])
        if isinstance(xpos, list):
            val = get_sheet_value(sheet, xpos[0], xpos[1])
        elif isinstance(xpos, str):
            if xpos not in xlsinfo:
                continue
            if not isinstance(xlsinfo[xpos][0], int):
                logger.error(f'error there not "{xpos}" in {xlsinfo}')
            xpos = [xlsinfo['flexiblepos'][2], xlsinfo[xpos][0]]
            val = get_sheet_value(sheet, xpos[0], xpos[1])
        else:
            continue
        
        if val == None:
            logger.error(f"get sheet value error {xpos}")
        cellstr = get_word_config_str(1, mval, 'number')
        if cellstr == None:
            cell.text = f"{val}"
        elif cellstr == '%':
            cell.text = "%.02f%%" % (val*100)
        else:
            cell.text = f"{cellstr}" % (val)
        set_doc_cell_format(cell, mval, 2)

        if mval['wpos'] == [2, 6]:
            isheaderchange = True
    return isheaderchange


def fill_doc_table_info(wtb, sheet, xlsinfo):
    docname, mode = get_doc_fill_base_info(xlsinfo['code'], xlsinfo['daterange'][0])
    if mode == None:
        return

    # 产品名称
    cell = wtb.cell(0, 0)
    pname = get_product_name_prefix(os.path.basename(xlsinfo['excel']))
    # suffix = get_product_name_prefix(cell.text, order=1).replace('\r', '').replace('\n', '')
    cell.text = ""  # 清空原内容
    run = cell.paragraphs[0].add_run(f'{pname}{docname}')
    run.bold = True
    cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER  # 水平居中
    
    isheaderchange = False
    if xlsinfo['filltable']:
        # 起始日期
        cell = wtb.cell(1, 1)
        cell.text = ""  # 清空原内容
        run = cell.paragraphs[0].add_run(xlsinfo['daterange'][0].strftime("%Y/%m/%d"))
        
        # 计算日期
        cell = wtb.cell(1, 3)
        cell.text = ""  # 清空原内容
        run = cell.paragraphs[0].add_run(xlsinfo['daterange'][2].replace('-', '/'))

        isheaderchange = fill_doc_table_dynamic_info(mode, wtb, sheet, xlsinfo)
    
    if isheaderchange == False:
        for key, mval in mode.items():
            if 'wpos' not in mval:
                continue
            if mval['wpos'] == [2, 6]:
                tempmode = {}
                tempmode[key] = mval
                isheaderchange = fill_doc_table_dynamic_info(tempmode, wtb, sheet, xlsinfo)
    if isheaderchange:
        return
    
    if xlsinfo['fillpicture']:
        # 周涨幅
        maxrow = xlsinfo['flexiblepos'][2]
        val = get_sheet_value(sheet, maxrow-1, 3)
        val1 = get_sheet_value(sheet, maxrow, 3)
        cell = wtb.cell(1, 5)
        cell.text = ""  # 清空原内容
        run = cell.paragraphs[0].add_run("%.02f%%" % ((val1 - val)/val*100))

def fill_doccell_by_excelinfo(sheet, wordpath, xlsinfo):
    if not os.path.exists(wordpath):
        return
    doc = Document(wordpath)
    tb = doc.tables[0]
    extend_doc_table(tb, sheet, xlsinfo)
    fill_doc_table_info(tb, sheet, xlsinfo)
    for row in tb.rows:
        for cell in row.cells:
            cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER# 垂直居中
            cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
            # 水平居中（需操作段落）
            for paragraph in cell.paragraphs:
                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                for run in paragraph.runs:
                     # 设置英文字体
                    run.font.name = "微软雅黑"
                    # 设置中文字体（通过东亚字体属性）
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')
                    # 设置字号为小五（对应9磅）
                    run.font.size = Pt(9)
    doc.save(wordpath) 
    sheetname = xlsinfo['sheetname']
    if sheetname.find('（日）') > 0:
        logging.info(f"fill word data pass {sheetname} {'日净值' if xlsinfo['filltable'] else '周净值'}{'周图' if xlsinfo['fillpicture'] == False else '日图'}")
    else:
        logging.info(f"fill word data pass {sheetname} {'日净值' if xlsinfo['filltable'] == False else '周净值'}{'周图' if xlsinfo['fillpicture'] else '日图'}")
    
    # pngpath = xlsinfo['excel'].replace('.xlsx', '.png')
    # replace_word_png(wordpath, pngpath)
